# 模块名和模块测试APP名称
MODULE_NAME       := sdriver_demo
MODULE_NAME       += 
MODULE_NAME       += 
MODULE_LOAD_SH    := module_load.sh

KO_MODULE_FILE    := $(addsuffix .ko, $(MODULE_NAME))        # 添加后缀
OBJ_M_O_FILE      := $(patsubst %.ko, %.o, $(KO_MODULE_FILE))# 替换成.o结尾的文件

ARCH              ?= arm
MAKE_PARAM        :=
CURRENT_PATH      := $(shell pwd)

KERNEL_KO_RELEASE  = $(shell git rev-parse --verify --short HEAD) # Kbuild.include会使用

ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif
ROOT_PERMISSION   ?= sudo
#=====================================================
# 源文件目录、头文件目录
INCDIRS 		  := ./ 			   
SRCDIRS			  := ./

INCLUDE			  := $(patsubst %, -I %, $(INCDIRS))
#=====================================================
# NFS 共享目录
TFTP_SERVER       ?= ~/3tftp
NFS_SERVER        ?= ~/4nfs

TFTP_DIR          ?= $(TFTP_SERVER)
ROOTFS_ROOT_DIR   ?= $(NFS_SERVER)/imx6ull_rootfs
# ROOTFS_MODULE_DIR 可以被上层makefile中导出的同名变量覆盖
#ROOTFS_MODULE_DIR ?= $(ROOTFS_ROOT_DIR)/lib/modules/4.19.71-00007-g51f3cd8ec-dirty
ROOTFS_MODULE_DIR ?= $(ROOTFS_ROOT_DIR)/drivers_demo
# 为什么有下面这个？因为在make uninstall的时候想一个rm删除所有对应的ko
# 但是，使用cd命令无法进入根文件系统对应的位置，所以这里加入绝对路径
ROOTFS_KO_PATH    := $(patsubst %, $(ROOTFS_MODULE_DIR)/%, $(KO_MODULE_FILE)) # 获取根文件系统中几个驱动的绝对路径

#=====================================================
ifeq ($(KERNELRELEASE),)

# 编译版本和时间相关的变量定义
include Kbuild.include
srctree              := .
timestamp_h          := timestamp_autogenerated.h
version_h            := version_autogenerated.h

# 选择可执行文件运行的平台
ifeq ($(ARCH), arm)
  KERNELDIR            ?= ~/7Linux/imx6ull-kernel
  CROSS_COMPILE_PREFIX ?= arm-linux-gnueabihf-
else
  KERNELDIR            ?= /lib/modules/$(shell uname -r)/build
  CROSS_COMPILE_PREFIX ?=
endif

MAKE_PARAM           += ARCH=$(ARCH)
MAKE_PARAM           += CROSS_COMPILE=$(CROSS_COMPILE_PREFIX)

CC                   := $(CROSS_COMPILE_PREFIX)gcc
LD                   := $(CROSS_COMPILE_PREFIX)ld

export CC LD srctree

# 编译模块和测试程序
all: $(timestamp_h) $(version_h) modules

modules:
	$(MAKE) $(MAKE_PARAM) -C $(KERNELDIR) M=$(CURRENT_PATH) modules $(INCLUDE)

modules_install:
	$(MAKE) $(MAKE_PARAM) -C $(KERNELDIR) M=$(CURRENT_PATH) modules INSTALL_MOD_PATH=$(ROOTFS_MODULE_DIR) modules_install

$(timestamp_h): $(srctree)/Makefile FORCE
	$(call filechk,timestamp_autogenerated.h)
	
$(version_h): $(srctree)/Makefile FORCE
	$(call filechk,version_autogenerated.h)

# 拷贝相关文件到nfs共享目录
install:
	$(Q)$(ROOT_PERMISSION) cp -vf *.ko $(ROOTFS_MODULE_DIR)
	$(Q)$(ROOT_PERMISSION) cp -vf $(MODULE_LOAD_SH) $(ROOTFS_MODULE_DIR)

uninstall:
	$(Q)$(ROOT_PERMISSION) rm -vf $(ROOTFS_KO_PATH)
	$(Q)$(ROOT_PERMISSION) rm -vf $(ROOTFS_MODULE_DIR)/$(MODULE_LOAD_SH)

PHONY += FORCE
FORCE:

PHONY += clean
clean:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
	$(Q)rm -rf $(timestamp_h)
	$(Q)rm -rf $(version_h)
	

.PHONY: $(PHONY)

help:
	@echo "\033[1;32m================================ Help ================================\033[0m"
	@echo "Ubuntu may need to add sudo:"
	@echo "insmod <module_name>.ko   # Load module"
	@echo "rmmod <module_name>       # Uninstall the module"
	@echo "dmesg -C                  # Clear the kernel print information"
	@echo "lsmod                     # Check the kernel modules that have been inserted"
	@echo "dmesg                     # View information printed by the kernel"
	@echo "file <module_name>.ko     # View \".Ko\" file information"
	@echo ""
	@echo "make ARCH=x86_64          # x86_64 platform"
	@echo "make                      # arm platform"
	@echo "\033[1;32m======================================================================\033[0m"

print:
	$(Q)echo "TFTP_SERVER           : $(TFTP_SERVER)"
	$(Q)echo "NFS_SERVER            : $(NFS_SERVER)"
	$(Q)echo "ROOTFS_MODULE_DIR     : $(ROOTFS_MODULE_DIR)"
	$(Q)echo "ROOTFS_KO_PATH        : $(ROOTFS_KO_PATH)"
	$(Q)echo "KO_MODULE_FILE        : $(KO_MODULE_FILE)"
	$(Q)echo "KERNELDIR             : $(KERNELDIR)"
	$(Q)echo "INCLUDE               : $(INCLUDE)"
	$(Q)echo "ARCH                  : $(ARCH)"
	$(Q)echo "ARCH1                 : $(ARCH1)"
	$(Q)echo "CC                    : $(CC)"
	$(Q)echo "MAKE_PARAM            : $(MAKE_PARAM)"
else
CONFIG_MODULE_SIG = n
obj-m            += $(OBJ_M_O_FILE)
endif

#=====================================================
# 一些简单的注释笔记
# 符号	                   含义	                                         变量类型
#  =	递归赋值，当变量展开时，优先从后面展开	                            延时变量
# :=	该变量立即赋值（会覆盖前面的值），当变量展开时，优先从前面展开	       立即变量
# ?=	若前面没有定义该变量，则此处赋值，如果前面已经定义了，则此处不再赋值	延时变量
# +=	追加赋值	                                                     立即变量
#
# $<	第一个依赖文件的名称
# $@	目标文件的完整名称
# $^	所有不重复的目标依赖文件，以空格分开
# $?	所有时间戳比目标文件晚的的依赖文件，并以空格分开
